package com.lyf.scm.plan.domain.repository;

import com.lyf.scm.common.constants.BigDataEsConstants;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.EsConmulEnum;
import com.lyf.scm.common.enums.ResponseMsg;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.plan.api.dto.EsQueryDTO;
import com.lyf.scm.plan.insfrastructure.db.dataobject.es.SalesPlanEsEntity;
import com.rome.arch.core.exception.RomeException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

import static org.elasticsearch.index.query.QueryBuilders.rangeQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;

/**
 * description:
 *
 * @author: haodong
 * @data: 2020/10/19 11:38
 */
@Service
public class SalesPlanOtherEsRepository {

    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    public List<SalesPlanEsEntity> listPageQuery(EsQueryDTO esQuery) {
        BoolQueryBuilder queryBuilder = getBoolQueryBuilder(esQuery);
        SearchQuery query = new NativeSearchQueryBuilder()
                .withQuery(queryBuilder)
                .withIndices(BigDataEsConstants.INDEX_NAME_PLAN_SALES_PLAN)
                .withPageable(PageRequest.of(CommonConstants.ZERO, CommonConstants.BIG_DATA_PAGE_SIZE))
                .build();
        return elasticsearchTemplate.queryForList(query, SalesPlanEsEntity.class);
    }

    /**
     * 获取查询条件
     *
     * @param baseSearch
     * @return
     */
    private BoolQueryBuilder getBoolQueryBuilder(EsQueryDTO baseSearch) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        if (StringUtils.isNotEmpty(baseSearch.getImportDate()) && StringUtils.isNotEmpty(baseSearch.getStartDate()) && StringUtils.isNotEmpty(baseSearch.getEndDate())) {
            queryBuilder.filter(rangeQuery(EsConmulEnum.DATE_KEYWORD.getFName()).gt(baseSearch.getStartDate())
                    .lte(baseSearch.getEndDate()));

            queryBuilder.filter(rangeQuery(EsConmulEnum.IMPORT_KEYWORD.getFName()).gte(baseSearch.getStartDate())
                    .lt(baseSearch.getImportDate()));
        } else if (StringUtils.isNotEmpty(baseSearch.getStartDate()) && StringUtils.isNotEmpty(baseSearch.getEndDate())) {
            queryBuilder.filter(rangeQuery(EsConmulEnum.DATE_KEYWORD.getFName()).gte(baseSearch.getStartDate())
                    .lte(baseSearch.getEndDate()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getTypeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.PLAN_TYPE.getFName(), baseSearch.getTypeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getWarehouseCodeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.WAREHOUSE_KEYWORD.getFName(), baseSearch.getWarehouseCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getLayeredCodeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.LEVEL_KEYWORD.getFName(), baseSearch.getLayeredCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getChannelCodeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.CHANNEL_KEYWORD.getFName(), baseSearch.getChannelCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getPermissionChannelList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.CHANNEL_KEYWORD.getFName(), baseSearch.getPermissionChannelList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getAreaCodeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.AREA_KEYWORD.getFName(), baseSearch.getAreaCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getBusinessNo())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.BUSINESS_KEYWORD.getFName(), baseSearch.getBusinessNo()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getActivityCodeList())) {
            queryBuilder.filter(getShouldQuery(EsConmulEnum.ACTIVITY_KEYWORD.getFName(), baseSearch.getActivityCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getQueryAreaCodeList())) {
            queryBuilder.filter(getAreaQuery(baseSearch.getQueryAreaCodeList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getPermissionAreaList())) {
            queryBuilder.filter(getAreaQuery(baseSearch.getPermissionAreaList()));
        }
        if (CollectionUtils.isNotEmpty(baseSearch.getCategoryCodeList())) {
            queryBuilder.filter(getCateQuery(baseSearch.getCategoryCodeList()));
        }
        return queryBuilder;
    }

    private QueryBuilder getCateQuery(List<SalesPlanSelectDTO> categoryCodeList) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        categoryCodeList.forEach(val -> {
            switch (val.getLevel()) {
                case 2:
                    queryBuilder.should(termQuery(EsConmulEnum.PRI_KEYWORD.getFName(), val.getCode()));
                    break;
                case 3:
                    queryBuilder.should(termQuery(EsConmulEnum.SEC_KEYWORD.getFName(), val.getCode()));
                    break;
                case 4:
                    queryBuilder.should(termQuery(EsConmulEnum.TER_KEYWORD.getFName(), val.getCode()));
                    break;
                case 5:
                    queryBuilder.should(termQuery(EsConmulEnum.SKU_KEYWORD.getFName(), val.getCode()));
                    break;
                default:
                    throw new RomeException(ResponseMsg.PARAM_ERROR.getCode(), ResponseMsg.PARAM_ERROR.getMsg());
            }
        });
        return queryBuilder;
    }

    private QueryBuilder getAreaQuery(List<SalesPlanSelectDTO> areaCodeList) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        areaCodeList.forEach(val -> {
            switch (val.getLevel()) {
                case 1:
                    queryBuilder.should(termQuery(EsConmulEnum.PROVINCE_CODE_KEYWORD.getFName(), val.getCode()));
                    break;
                case 2:
                    queryBuilder.should(termQuery(EsConmulEnum.CITY_CODE_KEYWORD.getFName(), val.getCode()));
                    break;
                case 3:
                    queryBuilder.should(termQuery(EsConmulEnum.COUNTY_CODE_KEYWORD.getFName(), val.getCode()));
                    break;
                case 4:
                    queryBuilder.should(termQuery(EsConmulEnum.STORE_KEYWORD.getFName(), val.getCode()));
                    break;
                default:
                    throw new RomeException(ResponseMsg.PARAM_ERROR.getCode(), ResponseMsg.PARAM_ERROR.getMsg());
            }
        });
        return queryBuilder;
    }

    private QueryBuilder getShouldQuery(String key, List<String> codeList) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        codeList.forEach(code -> queryBuilder.should(termQuery(key, code)));
        return queryBuilder;
    }
}
